module.exports = function(selectorHandlerDict, superclass) {
  var uniqueClassName =
    "MochaJSDelegate_DynamicClass_" + NSUUID.UUID().UUIDString();

  var delegateClassDesc = MOClassDescription.allocateDescriptionForClassWithName_superclass_(
    uniqueClassName,
    superclass || NSObject
  );

  delegateClassDesc.registerClass();

  // Storage Handlers
  var handlers = {};

  // Define interface
  this.setHandlerForSelector = function(selectorString, func) {
    var handlerHasBeenSet = selectorString in handlers;
    var selector = NSSelectorFromString(selectorString);

    handlers[selectorString] = func;

    /*
      For some reason, Mocha acts weird about arguments: https://github.com/logancollins/Mocha/issues/28
      We have to basically create a dynamic handler with a likewise dynamic number of predefined arguments.
    */
    if (!handlerHasBeenSet) {
      var args = [];
      var regex = /:/g;
      while (regex.exec(selectorString)) {
        args.push("arg" + args.length);
      }

      var dynamicFunction = eval(
        "(function (" +
          args.join(", ") +
          ") { return handlers[selectorString].apply(this, arguments); })"
      );

      delegateClassDesc.addInstanceMethodWithSelector_function_(
        selector,
        dynamicFunction
      );
    }
  };

  this.removeHandlerForSelector = function(selectorString) {
    delete handlers[selectorString];
  };

  this.getHandlerForSelector = function(selectorString) {
    return handlers[selectorString];
  };

  this.getAllHandlers = function() {
    return handlers;
  };

  this.getClass = function() {
    return NSClassFromString(uniqueClassName);
  };

  this.getClassInstance = function() {
    return NSClassFromString(uniqueClassName).new();
  };

  // Convenience
  if (typeof selectorHandlerDict === "object") {
    for (var selectorString in selectorHandlerDict) {
      this.setHandlerForSelector(
        selectorString,
        selectorHandlerDict[selectorString]
      );
    }
  }
};
